﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Kokomo.PeInspector.Settings;
using System.Reflection;
using Kokomo.PeInspector.Reflection.Disassembly;
using Kokomo.Environment.Documents;

namespace Kokomo.PeInspector.Reflection
{
	/// <summary>
	/// Exposes host functionality for displaying metadata.
	/// </summary>
	public interface IMetadataHost
	{
		/// <summary>
		/// Creates a <see cref="TreeNodeViewModel"/> to display a member.
		/// </summary>
		/// <param name="member">The member to display.</param>
		/// <returns>The <see cref="TreeNodeViewModel"/> initialized to display <paramref name="member"/></returns>
		/// <exception cref="ArgumentNullException"><paramref name="member"/> is <c>null</c>.</exception>
		TreeNodeViewModel CreateMemberNode(MemberInfo member);
		///// <summary>
		///// Gets a <see cref="MemberViewInfo"/> for a member.
		///// </summary>
		///// <param name="member">The member.</param>
		///// <returns>The <see cref="MemberViewInfo"/> describing <paramref name="member"/>.</returns>
		///// <exception cref="ArgumentNullException"><paramref name="member"/> is <c>null</c>.</exception>
		//MemberViewInfo GetMemberViewInfo(MemberInfo member);
		/// <summary>
		/// Gets a <see cref="MethodDecompilation"/> for a method.
		/// </summary>
		/// <param name="method">The method to disassemble.</param>
		/// <returns>The <see cref="MethodDecompilation"/> for <paramref name="method"/>.</returns>
		/// <exception cref="ArgumentNullException"><paramref name="method"/> is <c>null</c>.</exception>
		/// <remarks>
		/// Calling this method rather than using <see cref="MsilDecompiler"/>
		/// allows the host to apply user preferences or cache the results.
		/// </remarks>
		MethodDecompilation GetDisassemblyResult(MethodBase method);
		/// <summary>
		/// Gets the dependencies of a method.
		/// </summary>
		/// <param name="method"></param>
		/// <returns>A list of <see cref="MsilDependency"/> representing dependencies of <paramref name="method"/>.</returns>
		/// <remarks>
		/// Calling this method rather than using <see cref="MsilDecompiler"/>
		/// allows the host to apply user preferences or cache the results.
		/// </remarks>
		IEnumerable<MsilDependency> GetDependenciesOf(MethodBase method);
		///// <summary>
		///// Gets the text
		///// </summary>
		///// <param name="type"></param>
		///// <param name="context"></param>
		///// <returns></returns>
		//string GetTypeReferenceText(Type type, MemberInfo context);

		//void BuildSourceDocument(Assembly assembly, ICodeWriter codeWriter);
		//void BuildSourceDocument(MemberInfo member, ICodeWriter codeWriter);

		///// <summary>
		///// Gets the view settings.
		///// </summary>
		///// <seealso cref="ViewSettings"/>
		//ViewSettings ViewSettings { get; }

		#region Commands
		/// <summary>
		/// Gets the <c>Open New View</c> command.
		/// </summary>
		/// <remarks>
		/// If the caller specifies an argument, this command
		/// opens a new view and navigates to the argument.
		/// If the argument is <c>null</c>, the new view
		/// displays the object from the current view.
		/// </remarks>
		ICommand OpenNewViewCommand { get; }

		ICommand ViewModuleDetailsCommand { get; }
		ICommand ExportAssemblySourceCodeCommand { get; }
		#endregion

		void BuildSourceDocument(Assembly assembly, ICodeWriter writer);
		void BuildMsilDocument(MemberInfo member, ICodeWriter writer);

		/// <summary>
		/// Gets the <see cref="IAssemblyListHost"/> owning this
		/// instance.
		/// </summary>
		IAssemblyListHost AssemblyListHost { get; }
	}
}
